package LeetCode;

public class LC_639_DecodeWaysII {

    public static void main(String[] args) {

    }

    public class Solution {
        public int numDecodings(String s) {
            char[] cs = s.toCharArray();
            long[] dp = new long[s.length() + 1];
            dp[0] = 1;
            dp[1] = s.charAt(0) == '*' ? 9 : 1;
            if (s.charAt(0) == '0') dp[1] = 0;
            for (int i = 2; i < dp.length; i++) {
                if (cs[i - 1] == '*') {
                    if (cs[i - 2] == '*')
                        dp[i] = 9 * dp[i - 1] + 15 * dp[i - 2];
                    else if (cs[i - 2] >= '3')
                        dp[i] = 9 * dp[i - 1];
                    else if (cs[i - 2] == '2')
                        dp[i] = 9 * dp[i - 1] + 6 * dp[i - 2];
                    else if (cs[i - 2] == '1')
                        dp[i] = 9 * dp[i - 1] + 9 * dp[i - 2];
                    else
                        dp[i] = 9 * dp[i - 1];
                } else if (cs[i - 1] >= '7') {
                    if (cs[i - 2] == '*' || cs[i - 2] == '1')
                        dp[i] = dp[i - 1] + dp[i - 2];
                    else
                        dp[i] = dp[i - 1];
                } else if (cs[i - 1] == '0') {
                    if (cs[i - 2] == '*')
                        dp[i] = 2 * dp[i - 2];
                    else if (cs[i - 2] == '1' || cs[i - 2] == '2')
                        dp[i] = dp[i - 2];
                } else {
                    if (cs[i - 2] == '*')
                        dp[i] = dp[i - 1] + 2 * dp[i - 2];
                    else if (cs[i - 2] >= '3')
                        dp[i] = dp[i - 1];
                    else if (cs[i - 2] == '0')
                        dp[i] = dp[i - 1];
                    else
                        dp[i] = dp[i - 1] + dp[i - 2];
                }

                dp[i] = (long) (dp[i] % (1e9 + 7));
            }
            return (int) dp[cs.length];
        }
    }

    public class Solution_2 {
        int M = 1000000007;

        public int numDecodings(String s) {
            long[] dp = new long[s.length() + 1];
            dp[0] = 1;
            dp[1] = s.charAt(0) == '*' ? 9 : s.charAt(0) == '0' ? 0 : 1;
            for (int i = 1; i < s.length(); i++) {
                if (s.charAt(i) == '*') {
                    dp[i + 1] = 9 * dp[i];
                    if (s.charAt(i - 1) == '1')
                        dp[i + 1] = (dp[i + 1] + 9 * dp[i - 1]) % M;
                    else if (s.charAt(i - 1) == '2')
                        dp[i + 1] = (dp[i + 1] + 6 * dp[i - 1]) % M;
                    else if (s.charAt(i - 1) == '*')
                        dp[i + 1] = (dp[i + 1] + 15 * dp[i - 1]) % M;
                } else {
                    dp[i + 1] = s.charAt(i) != '0' ? dp[i] : 0;
                    if (s.charAt(i - 1) == '1')
                        dp[i + 1] = (dp[i + 1] + dp[i - 1]) % M;
                    else if (s.charAt(i - 1) == '2' && s.charAt(i) <= '6')
                        dp[i + 1] = (dp[i + 1] + dp[i - 1]) % M;
                    else if (s.charAt(i - 1) == '*')
                        dp[i + 1] = (dp[i + 1] + (s.charAt(i) <= '6' ? 2 : 1) * dp[i - 1]) % M;
                }
            }
            return (int) dp[s.length()];
        }
    }

}